package com.botann.projects.service;

import com.botann.projects.base.BaseService;
import com.botann.projects.base.UserDetail;
import com.botann.projects.base.UserDetailType;
import com.botann.projects.model.*;
import com.botann.projects.base.BaseService;
import com.botann.projects.base.UserDetail;
import com.botann.projects.base.UserDetailType;
import com.sun.istack.internal.NotNull;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Charging
 * ViewService
 * Created by 刘山国 on 2018/4/16.
 * Copyright (c) 2017 伯坦科技. All rights reserved
 */
@Service
public class ViewService extends BaseService implements ViewServiceIntf {
    @Override
    public Class loggerClass() {
        return ViewService.class;
    }


    /**
     * 加载一个menu 下面所有的页面,和页面的所有权限项  加载数据,都是未选中状态
     * @param menuId
     * @return List<View>
     */
    @Override
    public List<View> loadViews(@NotNull Integer menuId) {
        if (menuId<=0) throw sgErrorRuntimeException("参数错误,menuId=" + menuId);
        List<View> views = sessionQuery(View.class,conditions("menuId="),menuId);
        views.forEach((View view) -> {
            view.setShowing(false);
            List<ViewItem> items = loadViewItems(view.getId());
            items.forEach((ViewItem item) -> item.setShowing(false));
            view.setItems(items);
        });
        return views;
    }

    @Override
    public void addView(@NotNull Integer menuId, @NotNull String viewJson) {
        View newView = jsonToModel(viewJson,View.class);
        newView.setMenuId(menuId);
        checkViewSame(newView);
        sessionSave(newView);
    }

    @Override
    public void updateView(@NotNull String viewJson) {
        View newView = jsonToModel(viewJson,View.class);
        checkViewSame(newView);
        sessionFlushClear();
        sessionUpdate(newView);
    }

    private void checkViewSame( @NotNull View newView) {
        List<View> views = loadViews(newView.getMenuId());
        newView.setName(newView.getName().trim());
        newView.setUrl(newView.getUrl().trim());
        if (newView.getUrl().isEmpty()) throw sgErrorRuntimeException("页面路径不可为空");
        if (newView.getName().isEmpty()) throw sgErrorRuntimeException("页面名称不可为空");
        views.forEach((View view) -> {
            if (view.getId() != newView.getId()) {
                if (view.getName().equals(newView.getName())) throw sgErrorRuntimeException("不可添加,本菜单存在同名页面!");
                if (view.getUrl().equals(newView.getUrl())) throw sgErrorRuntimeException("不可添加,存在同路径页面!");
            }
         });
    }

    @Override
    public void deleteViews(@NotNull String deleteIdsJson) {
        List<Integer> deleteIds = jsonToListModel(deleteIdsJson,Integer.class);
        deleteIds.forEach((Integer deleteId) -> {
            sessionExecuteUpdate("delete from ViewItem where viewId = ?0 ", deleteId);
            sessionForceDelete(View.class,deleteId);
        });
    }

    @Override
    public List loadViewItems(@NotNull Integer viewId) {
        if (viewId<=0) throw sgErrorRuntimeException("参数错误,viewId=" + viewId);
        return sessionQuery(ViewItem.class,conditions("viewId="),viewId);
    }

    @Override
    public void addViewItem(@NotNull Integer viewId, @NotNull String viewItemJson) {
        ViewItem newViewItem = jsonToModel(viewItemJson,ViewItem.class);
        newViewItem.setViewId(viewId);
        checkViewItemSame(newViewItem);
        sessionSave(newViewItem);
    }

    @Override
    public void updateViewItem(@NotNull String viewItemJson) {
        ViewItem newViewItem = jsonToModel(viewItemJson,ViewItem.class);
        checkViewItemSame(newViewItem);
        sessionFlushClear();
        sessionUpdate(newViewItem);
    }

    private void checkViewItemSame(@NotNull ViewItem newViewItem) {
        List<ViewItem> viewItems = loadViewItems(newViewItem.getViewId());
        newViewItem.setName(newViewItem.getName().trim());
        if (newViewItem.getName().isEmpty()) throw sgErrorRuntimeException("名称不可为空");
        if (newViewItem.getProp().isEmpty()) throw sgErrorRuntimeException("key不可空");
        viewItems.forEach((ViewItem viewItem) -> {
            if (viewItem.getId() != newViewItem.getId()) {
                if (viewItem.getName().equals(newViewItem.getName())) throw sgErrorRuntimeException("不可添加,本页面存在同名页面项!");
                if (viewItem.getProp().equals(newViewItem.getProp())) throw sgErrorRuntimeException("不可添加,本页面存在同名key!");
            }
        });
    }

    @Override
    public void deleteViewItems(@NotNull String deleteIdsJson) {
        List<Integer> deleteIds = jsonToListModel(deleteIdsJson, Integer.class);
        deleteIds.forEach((Integer deleteId) -> sessionForceDelete(ViewItem.class,deleteId));
    }


    @Override
    public void deleteViewOrItems(List<View> views) {
        views.forEach((View view) -> {
            view.getItems().forEach((ViewItem item) -> {
                if (item.isShowing()) {
                    sessionExecuteUpdate("delete from RoleViewItem where itemId=?0 ", item.getId());
                    sessionForceDelete(item);
                }
            });
            if (view.isShowing()) {
                sessionExecuteUpdate("delete from RoleView where viewId=?0 ", view.getId());
                sessionForceDelete(view);
            }
        });
    }

    @Override
    public List loadRoleViews (@NotNull Integer roleId, @NotNull Integer menuId) {
        List<View> views = sessionQuery(View.class);
        views.forEach((View view) -> {
            RoleView roleView = sessionGet(RoleView.class, conditions("roleId=","viewId="), roleId,view.getId());
            if (roleView != null) {
                view.setShowing(true);
                view.getItems().forEach((ViewItem item) -> {
                    RoleViewItem roleViewItem = sessionGet(RoleViewItem.class,conditions("itemId=","roleViewId="),item.getId(),roleView.getId());
                    if (roleViewItem != null) {
                        item.setShowing(roleViewItem.isShowing());
                        item.setClickable(roleViewItem.isClickable());
                    }
                });
            }
        });
        return views;
    }

    @Override
    public void saveRoleViews (@NotNull Integer roleId, @NotNull List<View> views) {
        views.forEach((View view) -> {
            RoleView roleView = sessionGet(RoleView.class, conditions("roleId=","viewId="), roleId, view.getId());
            if (view.isShowing()) {
                if (roleView == null) {
                    roleView = new RoleView();
                    roleView.setRoleId(roleId);
                    roleView.setViewId(view.getId());
                    sessionFlushClear();
                    sessionSave(roleView);
                }
            } else {
                if (roleView != null) {
                    sessionForceDelete(RoleView.class,roleView.getId());
                }
            }
            if (roleView != null) {
                final RoleView finalRoleView = roleView;
                view.getItems().forEach((ViewItem item) -> {
                    RoleViewItem roleViewItem = sessionGet(RoleViewItem.class,conditions("itemId=","roleViewId="),item.getId(),finalRoleView.getId());
                    if (item.isShowing()) {
                        if (view.isShowing()) {
                            if (roleViewItem == null) {
                                roleViewItem = new RoleViewItem();
                                roleViewItem.setItemId(item.getId());
                                roleViewItem.setRoleViewId(finalRoleView.getId());
                                roleViewItem.setShowing(item.isShowing());
                                roleViewItem.setClickable(item.isClickable());
                                sessionFlushClear();
                                sessionSave(roleViewItem);
                            } else {
                                roleViewItem.setShowing(item.isShowing());
                                roleViewItem.setClickable(item.isClickable());
                                sessionFlushClear();
                                sessionUpdate(roleViewItem);
                            }
                        } else {
                            throw sgErrorRuntimeException("页面权限项显示,页面未显示!!");
//                        roleViewItem.setShowing(false);
//                        sessionFlushClear();
//                        sessionUpdate(roleViewItem);
                        }

                    } else {
                        if (roleViewItem != null) {
                            roleViewItem.setShowing(false);
                            sessionFlushClear();
                            sessionUpdate(roleViewItem);
                        }
                    }
                });
            }
        });
    }

    @Override
    public List<ViewItem> loadAuthorityViewItems(@NotNull Integer menuId, String url) {
        UserDetail userDetail = UserDetail.current();
        if (userDetail.getType() != UserDetailType.USER_ADMIN) throw sgErrorRuntimeException("暂无权限!");
        AdminUser adminUser = sessionGet(AdminUser.class,UserDetail.current().getId());
        Integer roleId = adminUser.getRoleId();
        if (url == null) {
            Menu menu = sessionGetNN(Menu.class,menuId);
            url = menu.getUrl();
        }
        View view = sessionGet(View.class,conditions("menuId=","url="),menuId,url);
        if (view == null) return null;
        List<ViewItem> items = sessionQuery(ViewItem.class,conditions("viewId="),view.getId());
        if (view != null) {
            RoleView roleView = sessionGet(RoleView.class,conditions("roleId=","viewId="),roleId,view.getId());
            if (roleView != null) {
                items.forEach((ViewItem item) -> {
                    RoleViewItem roleViewItem = sessionGet(RoleViewItem.class,conditions("itemId=","roleViewId="),item.getId(),roleView.getId());
                    if (roleViewItem != null) {
                        item.setClickable(roleViewItem.isClickable());
                        item.setShowing(roleViewItem.isShowing());
                    }
                });
            }
        }
        return items;
    }


    /**
     * 跟Menu的所有页面 加载所有的页面和页面权限项, 包含是否选中状态
     * @param menus
     * @param roleId roleId == null 加载所有
     * @param type
     * @return
     */
    @Override
    public List<Menu> loadAllMenuViews(List<Menu> menus, Integer roleId) {
        menus.forEach((Menu menu) ->
            menu.getChildren().forEach((Menu subMenu) -> {
                if (roleId == null) {
                    subMenu.setViews(loadRoleViews(roleId,subMenu.getId()));
                } else {
                    subMenu.setViews(loadViews(subMenu.getId()));
                }
            })
        );
        return menus;
    }

    /**
     * 更新 menu的页面和页面权限项 的选择状态
     * @param menus
     * @param roleId
     * @param type
     */
    @Override
    public void saveAllMenuViews(List<Menu> menus, Integer roleId) {
        menus.forEach((Menu menu) ->
                menu.getChildren().forEach((Menu subMenu) -> {
                    saveRoleViews(roleId, subMenu.getViews());
                })
        );
    }


    @Override
    public void deleteMenuViews(String menuViewsJson) {
        List<Menu> menus = jsonToListModel(menuViewsJson,Menu.class);
        menus.forEach((Menu menu) ->
            menu.getChildren().forEach((Menu subMenu) ->
                    deleteViewOrItems(subMenu.getViews())
            )
        );
    }
}
